﻿using System.Diagnostics;
using System.Collections.Generic;

namespace org.apache.lucene.analysis.pt
{

	/*
	 * Licensed to the Apache Software Foundation (ASF) under one or more
	 * contributor license agreements.  See the NOTICE file distributed with
	 * this work for additional information regarding copyright ownership.
	 * The ASF licenses this file to You under the Apache License, Version 2.0
	 * (the "License"); you may not use this file except in compliance with
	 * the License.  You may obtain a copy of the License at
	 *
	 *     http://www.apache.org/licenses/LICENSE-2.0
	 *
	 * Unless required by applicable law or agreed to in writing, software
	 * distributed under the License is distributed on an "AS IS" BASIS,
	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	 * See the License for the specific language governing permissions and
	 * limitations under the License.
	 */

	/// <summary>
	/// Portuguese stemmer implementing the RSLP (Removedor de Sufixos da Lingua Portuguesa)
	/// algorithm. This is sometimes also referred to as the Orengo stemmer.
	/// </summary>
	/// <seealso cref= RSLPStemmerBase </seealso>
	public class PortugueseStemmer : RSLPStemmerBase
	{
	  private static readonly Step plural, feminine, adverb, augmentative, noun, verb, vowel;

	  static PortugueseStemmer()
	  {
		IDictionary<string, Step> steps = parse(typeof(PortugueseStemmer), "portuguese.rslp");
		plural = steps["Plural"];
		feminine = steps["Feminine"];
		adverb = steps["Adverb"];
		augmentative = steps["Augmentative"];
		noun = steps["Noun"];
		verb = steps["Verb"];
		vowel = steps["Vowel"];
	  }

	  /// <param name="s"> buffer, oversized to at least <code>len+1</code> </param>
	  /// <param name="len"> initial valid length of buffer </param>
	  /// <returns> new valid length, stemmed </returns>
	  public virtual int stem(char[] s, int len)
	  {
		Debug.Assert(s.Length >= len + 1, "this stemmer requires an oversized array of at least 1");

		len = plural.apply(s, len);
		len = adverb.apply(s, len);
		len = feminine.apply(s, len);
		len = augmentative.apply(s, len);

		int oldlen = len;
		len = noun.apply(s, len);

		if (len == oldlen) // suffix not removed
		{
		  oldlen = len;

		  len = verb.apply(s, len);

		  if (len == oldlen) // suffix not removed
		  {
			len = vowel.apply(s, len);
		  }
		}

		// rslp accent removal
		for (int i = 0; i < len; i++)
		{
		  switch (s[i])
		  {
			case 'à':
			case 'á':
			case 'â':
			case 'ã':
			case 'ä':
			case 'å':
				s[i] = 'a';
				break;
			case 'ç':
				s[i] = 'c';
				break;
			case 'è':
			case 'é':
			case 'ê':
			case 'ë':
				s[i] = 'e';
				break;
			case 'ì':
			case 'í':
			case 'î':
			case 'ï':
				s[i] = 'i';
				break;
			case 'ñ':
				s[i] = 'n';
				break;
			case 'ò':
			case 'ó':
			case 'ô':
			case 'õ':
			case 'ö':
				s[i] = 'o';
				break;
			case 'ù':
			case 'ú':
			case 'û':
			case 'ü':
				s[i] = 'u';
				break;
			case 'ý':
			case 'ÿ':
				s[i] = 'y';
				break;
		  }
		}
		return len;
	  }
	}

}